package mailgod;

import processing.core.*;
public class GridLine {
	  float[][] p00, p01, p02, p10, p11, p12, p13, p14, p15, p20, p21, p22, p23, p30, p31, p32; ////plane-point coordinates for all beamers and shapes
	  float[][] sp00, sp01, sp02, sp10, sp11, sp12, sp13, sp14, sp15, sp20, sp21, sp22, sp23, sp30, sp31, sp32; ////space-point coordinates for all beamers and shapes
	  float[] points;
	  float[] pointsInSpace;
	  float xMin, xMax, yMin, yMax, zMin, zMax;
	  float planeValue;
	  int plane;
	  PVector[] set0_Point, set1_Point, set2_Point, set3_Point;
	  PVector[] set0_Vec, set1_Vec, set2_Vec, set3_Vec;
	  int[] set0_Shape, set1_Shape, set2_Shape, set3_Shape;
	  GridCoordinates gc_0, gc_1, gc_2, gc_3;

private PApplet parent;

	  public GridLine (PApplet p, float thePlaneValue, char thePlaneName) {
		  parent = p;
	    planeValue = thePlaneValue;
	    setPlane(thePlaneName);
	    setBoundaries ();
	    setPointArrays();  
	    setLines();
	  };

	  public void resetPlane(float thePlaneValue) {
	    planeValue = thePlaneValue;
	    resetArrays();
	    setLines();
	  }

	  public void incPlane(float thePlaneIncValue) {
	    planeValue += thePlaneIncValue;
	    resetArrays();
	    setLines();
	  }


	  public void setLines() {
	    gc_0 = new GridCoordinates(p00,sp00,set0_Point,set0_Vec,set0_Shape,0,this);
	    set0_Point = gc_0.getPointArray();
	    set0_Vec = gc_0.getSpacePointArray();
	    set0_Shape = gc_0.getShapeArray();

	    gc_0 = new GridCoordinates(p01,sp01,set0_Point,set0_Vec,set0_Shape,1,this);
	    set0_Point = gc_0.getPointArray();
	    set0_Vec = gc_0.getSpacePointArray();
	    set0_Shape = gc_0.getShapeArray();

	    gc_0 = new GridCoordinates(p02,sp02,set0_Point,set0_Vec,set0_Shape,2,this);
	    set0_Point = gc_0.getPointArray();
	    set0_Vec = gc_0.getSpacePointArray();
	    set0_Shape = gc_0.getShapeArray();

	    gc_1 = new GridCoordinates(p10,sp10,set1_Point,set1_Vec,set1_Shape,0,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p11,sp11,set1_Point,set1_Vec,set1_Shape,1,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p12,sp12,set1_Point,set1_Vec,set1_Shape,2,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p13,sp13,set1_Point,set1_Vec,set1_Shape,3,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p14,sp14,set1_Point,set1_Vec,set1_Shape,4,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p15,sp15,set1_Point,set1_Vec,set1_Shape,5,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_2 = new GridCoordinates(p20,sp20,set2_Point,set2_Vec,set2_Shape,0,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_2 = new GridCoordinates(p21,sp21,set2_Point,set2_Vec,set2_Shape,1,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_2 = new GridCoordinates(p22,sp22,set2_Point,set2_Vec,set2_Shape,2,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_2 = new GridCoordinates(p23,sp23,set2_Point,set2_Vec,set2_Shape,3,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_3 = new GridCoordinates(p30,sp30,set3_Point,set3_Vec,set3_Shape,0,this);
	    set3_Point = gc_3.getPointArray();
	    set3_Vec = gc_3.getSpacePointArray();
	    set3_Shape = gc_3.getShapeArray();

	    gc_3 = new GridCoordinates(p31,sp31,set3_Point,set3_Vec,set3_Shape,1,this);
	    set3_Point = gc_3.getPointArray();
	    set3_Vec = gc_3.getSpacePointArray();
	    set3_Shape = gc_3.getShapeArray();

	    gc_3 = new GridCoordinates(p32,sp32,set3_Point,set3_Vec,set3_Shape,2,this);
	    set3_Point = gc_3.getPointArray();
	    set3_Vec = gc_3.getSpacePointArray();
	    set3_Shape = gc_3.getShapeArray();




	    //println(set0_Vec);
	    //println(set1_Vec);
	    //println(set2_Vec);
	    //println(set3_Vec);
	    //    println(set0_Shape);
	     //   println(set1_Shape);
	    //    println(set2_Shape);
	    //    println(set3_Shape);
	        
//	        println(set3_Vec[0]);
	    
	  };

	  public void drawLineInSpace(int setID, int shapeID) {
	    PVector[] vertices;
	    vertices = null;
	    switch(setID) {
	    case 0:
	      if (set0_Shape != null) {
	        for (int i = 0; i < set0_Shape.length; i++) {
	          if (set0_Shape[i] == shapeID) {
	            PVector p = set0_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	        //if (vertices != null) drawVertices(vertices);
	      }
	      break;
	    case 1:
	      if (set1_Shape != null) {
	        for (int i = 0; i < set1_Shape.length; i++) {
	          if (set1_Shape[i] == shapeID) {
	            PVector p = set1_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	        //if (vertices != null) drawVertices(vertices);
	      }

	      break;
	    case 2:
	      if (set2_Shape != null) {
	        for (int i = 0; i < set2_Shape.length; i++) {
	          if (set2_Shape[i] == shapeID) {
	            PVector p = set2_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	       // if (vertices != null) drawVertices(vertices);
	      }

	      break;
	    case 3:
	      if (set3_Shape != null) {
	        for (int i = 0; i < set3_Shape.length; i++) {
	          if (set3_Shape[i] == shapeID) {
	            PVector p = set3_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	       // if (vertices != null) drawVertices(vertices);
	      }
	      break;
	    }
	     if (vertices != null) drawVertices(vertices);
	  }



	  public void drawLineInPlane(int setID, int shapeID) {
	    PVector[] vertices;
	    vertices = null;

	    switch(setID) {
	    case 0:
	          if (set0_Shape != null) {
	      for (int i = 0; i < set0_Shape.length; i++) {
	        if (set0_Shape[i] == shapeID) {
	          PVector p = set0_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }
	          }
	      break;
	    case 1:
	              if (set1_Shape != null) {
	      for (int i = 0; i < set1_Shape.length; i++) {
	        if (set1_Shape[i] == shapeID) {
	          PVector p = set1_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }
	          }
	      break;
	    case 2:
	      if (set2_Shape != null) {
	      for (int i = 0; i < set2_Shape.length; i++) {
	        if (set2_Shape[i] == shapeID) {
	          PVector p = set2_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }
	          }
	      break;
	    case 3:
	    if (set3_Shape != null) {
	      for (int i = 0; i < set3_Shape.length; i++) {
	                  
	        if (set3_Shape[i] == shapeID) {
	          PVector p = set3_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }

	          }
	      break;
	    }
	     if (vertices != null) drawVertices(vertices);
	  }

	  public void drawVertices(PVector[] v) {
	      for (int i = 0; i < v.length; i+=2) {
	        int j = (i+1)%v.length;
	        parent.beginShape();
	        parent.vertex(v[i].x,v[i].y,v[i].z);
	        parent.vertex(v[j].x,v[j].y,v[j].z);
	        parent.endShape();
	      }

//	    for (int i = 0; i < v.length; i++) {
//	      for (int j = 0; j < v.length; j++) {
//	        if (i != j) {
//	          beginShape();
//	          vertex(v[i].x,v[i].y,v[i].z);
//	          vertex(v[j].x,v[j].y,v[j].z);
//	          endShape();
//	        }
//	      }
//	    }
	  };









	  public void setPlane(char c) {
	    if (c == 'x') plane = 0;
	    if (c == 'y') plane = 1;
	    if (c == 'z') plane = 2;
	  };

	  public void  setBoundaries () {
	    xMin = getBoundary(0,-1);
	    xMax = getBoundary(0,1);
	    yMin = getBoundary(1,-1);
	    yMax = getBoundary(1,1);
	    zMin = getBoundary(2,-1);
	    zMax = getBoundary(2,1);
//	    println("xMin: " + xMin);
//	    println("xMax: " + xMax);
//	    println("yMin: " + yMin);
//	    println("yMax: " + yMax);
//	    println("zMin: " + zMin);
//	    println("zMax: " + zMax);
	  }

	  public void setPointArrays() {
	    p00 =  SpiralRender.points00;
	    p01 =  SpiralRender.points01;
	    p02 =  SpiralRender.points02;
	    p10 =  SpiralRender.points10;
	    p11 =  SpiralRender.points11;
	    p12 =  SpiralRender.points12;
	    p13 =  SpiralRender.points13;
	    p14 =  SpiralRender.points14;
	    p15 =  SpiralRender.points15;
	    p20 =  SpiralRender.points20;
	    p21 =  SpiralRender.points21;
	    p22 =  SpiralRender.points22;
	    p23 =  SpiralRender.points23;
	    p30 =  SpiralRender.points30;
	    p31 =  SpiralRender.points31;
	    p32 =  SpiralRender.points32;
	    sp00 =  SpiralRender.spacePoints00;
	    sp01 =  SpiralRender.spacePoints01;
	    sp02 =  SpiralRender.spacePoints02;
	    sp10 =  SpiralRender.spacePoints10;
	    sp11 =  SpiralRender.spacePoints11;
	    sp12 =  SpiralRender.spacePoints12;
	    sp13 =  SpiralRender.spacePoints13;
	    sp14 =  SpiralRender.spacePoints14;
	    sp15 =  SpiralRender.spacePoints15;
	    sp20 =  SpiralRender.spacePoints20;
	    sp21 =  SpiralRender.spacePoints21;
	    sp22 =  SpiralRender.spacePoints22;
	    sp23 =  SpiralRender.spacePoints23;
	    sp30 =  SpiralRender.spacePoints30;
	    sp31 =  SpiralRender.spacePoints31;
	    sp32 =  SpiralRender.spacePoints32;
	  }


	  public float getBoundary(int plane, int theSign) { ////plane: 0 -> x, 1 -> y, 2 -> z
	    float retVal;
	    if (theSign == 1 ) {
	      retVal = PApplet.MAX_FLOAT*(-1);
	    } 
	    else {
	      retVal = PApplet.MAX_FLOAT;
	    }
	    retVal = getArrayMinMax(SpiralRender.spacePoints00, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints01, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints02, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints10, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints11, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints12, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints13, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints14, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints15, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints20, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints21, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints22, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints23, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints30, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints31, plane, retVal, theSign);
	    retVal = getArrayMinMax(SpiralRender.spacePoints32, plane, retVal, theSign);
	    return retVal;
	  }

	  public float getArrayMinMax (float[][] theArray, int ind, float mmVal, int sign) {
	    float retVal = mmVal;
	    if (sign == 1) {
	      for (int i = 0; i < theArray.length; i++) {
	        if (theArray[i][ind] > retVal) retVal = theArray[i][ind];
	      }
	    } 
	    else {
	      for (int i = 0; i < theArray.length; i++) {
	        if (theArray[i][ind] < retVal) retVal = theArray[i][ind];
	      }
	    }
	    return retVal;
	  }

	  public void resetArrays () {
	    set0_Point = null;
	    set1_Point = null;
	    set2_Point = null;
	    set3_Point = null;
	    set0_Vec = null;
	    set1_Vec = null;
	    set2_Vec = null;
	    set3_Vec = null;
	    set0_Shape = null;
	    set1_Shape = null;
	    set2_Shape = null;
	    set3_Shape = null;
	  }
	}
